package net.blank.ui.core
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.events.TextEvent;
	import flash.text.engine.ContentElement;
	import flash.text.engine.TextJustifier;
	import flash.text.engine.TextLine;
	import flash.text.engine.TextLineMirrorRegion;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	import flash.utils.Dictionary;
	
	import net.blank.blankLoader.SequenceLoader;
	
	/**
	 * 点击超链接时触发
	 */
	[Event(name="link", type="flash.events.TextEvent")]
	
	/**
	 * 方本被渲染后派发,一般用于确定实际文本的高度(因为在渲染之前是不能知道其高度的)
	 */
	[Event(name="update_text_complete", type="net.blank.ui.core.RenderOptEvent")]
	
	/**
	 * XML标签,可用于显示HTML文本,使用时注意以下事项
	 * <li>默认 mouseEnabled 值为 false</li> 
	 * <li>默认 mouseChildren 值为 false ,启用超链接时应将 mouseChildren 设置为 true</li>
	 * <li>不支持文本输入,如果要启用文本输入功能,请使用 TextInput</li>
	 * <li>没有 textWidth 和 textHeight 属性,在 height 足以容纳全部文本显示时 contentHeight 为 textHeight </li>
	 * @author blank
	 * 
	 */
	public class XMLLabel extends UIComponent
	{
		/**
		 * 文本
		 */
		protected var _text:XML;
		
		/**
		 * 左边距
		 */
		protected var _paddingLeft:Number;
		
		/**
		 * 右边距
		 */
		protected var _paddingTop:Number;
		
		/**
		 * 上边距
		 */
		protected var _paddingRight:Number;
		
		/**
		 * 下边距
		 */
		protected var _paddingBottom:Number;
		
		/**
		 * 对齐方式
		 */
		protected var _hAlign:String;
		
		/**
		 * 垂直对齐方式
		 */
		protected var _vAlign:String;
		
		/**
		 * 行对齐方式
		 */
		protected var _lineJustifier:TextJustifier;
		
		/**
		 * 行间距(像素)
		 */
		protected var _lineGap:Number;
		
		/**
		 * 文本行的方向
		 */
		protected var _lineDirection:String;
		
		/**
		 * css样式表
		 */
		protected var _styleSheet:Dictionary;
		
		/**
		 * url对象缓存池(如果不指定,将使用系统缓存)
		 */
		protected var _urlCache:Dictionary;
		
		/**
		 * 文本行
		 */
		protected var _textLines:Vector.<TextLine>=new Vector.<TextLine>();
		
		/**
		 * 需要更新文本
		 */
		private var isNeedUpdateText:Boolean;
		
		/**
		 * 超链接事件接收器
		 */
		protected var link:EventDispatcher;
		
		/**
		 * 更新文本行
		 * 
		 */
		protected function updateTextLines():void{
			if(!_text){
				return;
			}
			
			var content:Vector.<ContentElement>=HTMLConverter.convert(_text,_styleSheet,sysMgt.sequenceLoader || new SequenceLoader(),_urlCache || sysMgt.urlCache,link);
			
			switch(_lineDirection){
				default:
				case Direction.HORIZONTAL:
					TextCreator.createTextLines_h_fixedGap(
						content,
						_textLines,
						this,
						_paddingLeft,
						_paddingTop,
						_width-_paddingLeft-_paddingRight,
						_height-_paddingTop-_paddingBottom,
						_hAlign,
						_vAlign,
						_lineGap,
						_lineJustifier,
						true
					);
					break;
				case Direction.VERTICAL:
					TextCreator.createTextLines_v_fixedGap(
						content,
						_textLines,
						this,
						_paddingLeft,
						_paddingTop,
						_width-_paddingLeft-_paddingRight,
						_height-_paddingTop-_paddingBottom,
						_vAlign,
						_hAlign,
						_lineGap,
						_lineJustifier,
						true
					);
					break;
			}
			
			if(hasEventListener(RenderEvent.RENDER_TEXT_COMPLETE)){
				dispatchEvent(new RenderEvent(RenderEvent.RENDER_TEXT_COMPLETE));
			}
		}
		
		override protected function update():void{
			super.update();
			
			if(isNeedUpdateText){
				updateTextLines();
				
				isNeedUpdateText=false;
			}
		}
		
		/**
		 * 更新文本
		 * 
		 */
		public function updateText():void{
			isNeedUpdateText=true;
			
			invalidate();
		}
		
		/**
		 * 大小发生改变,更新文本显示
		 * @param evt
		 * 
		 */
		protected function resizeHandler(evt:UIEvent):void{
			updateText();
		}
		
		/**
		 * 获取事件触发的超链接区域
		 * @param evt
		 * @return 
		 * 
		 */
		private function getLinkTextLineMirrorRegion(evt:Event):TextLineMirrorRegion{
			var tl:TextLine,mrs:Vector.<TextLineMirrorRegion>;
			if(evt.target is TextLine){
				tl=evt.target as TextLine;
				mrs=tl.mirrorRegions;
			}else if(
				evt.target.hasOwnProperty("parent")
				&&
				evt.target.parent is TextLine
			){
				tl=evt.target.parent;
				mrs=tl.mirrorRegions;
			}else{
				return null;
			}
			
			for each(var m:TextLineMirrorRegion in mrs){
				if(m.bounds.contains(tl.mouseX,tl.mouseY)){
					return m;
				}
			}
			return null;
		}
		
		/**
		 * 鼠标进入超链接
		 * @param evt
		 * 
		 */
		protected function link_mouseOverHandler(evt:MouseEvent):void{
			Mouse.cursor=MouseCursor.BUTTON;
		}
		
		/**
		 * 鼠标离开超链接
		 * @param evt
		 * 
		 */
		protected function link_mouseOutHandler(evt:MouseEvent):void{
			Mouse.cursor=MouseCursor.AUTO;
		}
		
		/**
		 * 鼠标点击超链接
		 * @param evt
		 * 
		 */
		protected function link_clickHandler(evt:MouseEvent):void{
			var m:TextLineMirrorRegion=getLinkTextLineMirrorRegion(evt);
			if(m){
				var te:TextEvent=new TextEvent(TextEvent.LINK);
				te.text=m.element.userData;
				dispatchEvent(te);
			}
		}
		
		/**
		 * 注册超链接的侦听器
		 * 
		 */
		protected function link_regListener():void{
			link.addEventListener(MouseEvent.MOUSE_OVER,link_mouseOverHandler);
			link.addEventListener(MouseEvent.MOUSE_OUT,link_mouseOutHandler);
			link.addEventListener(MouseEvent.CLICK,link_clickHandler);
		}
		
		/**
		 * 取消超链接的侦听器
		 * 
		 */
		protected function link_rmListener():void{
			link.removeEventListener(MouseEvent.MOUSE_OVER,link_mouseOverHandler);
			link.removeEventListener(MouseEvent.MOUSE_OUT,link_mouseOutHandler);
			link.removeEventListener(MouseEvent.CLICK,link_clickHandler);
		}
		
		/**
		 * XML标签,可用于显示HTML文本
		 * 
		 */
		public function XMLLabel(){
			link=new EventDispatcher();
			
			super();
			
			mouseEnabled=false;
			mouseChildren=false;
			
			link_regListener();
			
			addEventListener(UIEvent.RESIZE,resizeHandler);
		}
		
		/**
		 * XML,HTML文本
		 * @param value
		 * 
		 */
		public function set text(value:XML):void{
			if(value != _text){
				_text=value;
				
				updateText();
			}
		}
		public function get text():XML{
			return _text;
		}
		
		/**
		 * 左边距(文本到左边框的像素距离)
		 * @param value
		 * 
		 */
		public function set paddingLeft(value:Number):void{
			if(value != _paddingLeft){
				_paddingLeft=value;
				
				updateText();
			}
		}
		public function get paddingLeft():Number{
			return _paddingLeft;
		}
		
		/**
		 * 上边距(文本到上边框的像素距离)
		 * @param value
		 * 
		 */
		public function set paddingTop(value:Number):void{
			if(value != _paddingTop){
				_paddingTop=value;
				
				updateText();
			}
		}
		public function get paddingTop():Number{
			return _paddingTop;
		}
		
		/**
		 * 右边距(文本到右边框的像素距离)
		 * @param value
		 * 
		 */
		public function set paddingRight(value:Number):void{
			if(value != _paddingRight){
				_paddingRight=value;
				
				updateText();
			}
		}
		public function get paddingRight():Number{
			return _paddingRight;
		}
		
		/**
		 * 下边距(文本到下边框的像素距离)
		 * @param value
		 * 
		 */
		public function set paddingBottom(value:Number):void{
			if(value != _paddingBottom){
				_paddingBottom=value;
				
				updateText();
			}
		}
		public function get paddingBottom():Number{
			return _paddingBottom;
		}
		
		/**
		 * 对齐方式
		 * @param value
		 * 
		 */
		public function set hAlign(value:String):void{
			if(value != _hAlign){
				_hAlign=value;
				
				updateText();
			}
		}
		public function get hAlign():String{
			return _hAlign;
		}
		
		/**
		 * 垂直对齐方式
		 * @param value
		 * 
		 */
		public function set vAlign(value:String):void{
			if(value != _vAlign){
				_vAlign=value;
				
				updateText();
			}
		}
		public function get vAlign():String{
			return _vAlign;
		}
		
		/**
		 * 行对齐方式
		 * @param value
		 * 
		 */
		public function set lineJustifier(value:TextJustifier):void{
			if(value != _lineJustifier){
				_lineJustifier=value;
				
				updateText();
			}
		}
		public function get lineJustifier():TextJustifier{
			return _lineJustifier;
		}
		
		/**
		 * 行间距(像素)
		 * @param value
		 * 
		 */
		public function set lineGap(value:Number):void{
			if(value != _lineGap){
				_lineGap=value;
				
				updateText();
			}
		}
		public function get lineGap():Number{
			return _lineGap;
		}
		
		/**
		 * 文本行的方向
		 * @param value
		 * 
		 */
		public function set lineDirection(value:String):void{
			if(value != _lineDirection){
				_lineDirection=value;
				
				updateText();
			}
		}
		public function get lineDirection():String{
			return _lineDirection;
		}
		
		/**
		 * css样式表
		 * @param value
		 * 
		 */
		public function set styleSheet(value:Dictionary):void{
			if(value != _styleSheet){
				_styleSheet = value;
				
				updateText();
			}
		}
		public function get styleSheet():Dictionary{
			return _styleSheet;
		}
		
		/**
		 * url对象缓存池(如果不指定,将使用系统缓存)
		 * @param value
		 * 
		 */
		public function set urlCache(value:Dictionary):void{
			if(value != _urlCache){
				_urlCache=value;
				
				updateText();
			}
		}
		public function get urlCache():Dictionary{
			return _urlCache;
		}
		
		override public function reset():void{
			super.reset();
			
			_paddingLeft=2;
			_paddingTop=2;
			_paddingRight=2;
			_paddingBottom=2;
			
			_hAlign=Arrange.LEFT;
			_vAlign=Arrange.TOP;
			
			_lineJustifier=null;
			
			_lineGap=4;
			
			_styleSheet=null;
			_text=null;
			TextCreator.releaseTextLines(_textLines,this);
		}
		
		override public function destroy():void{
			super.destroy();
			
			TextCreator.releaseTextLines(_textLines,this);
			
			_styleSheet=null;
			_lineJustifier=null;
		}
	}
}